﻿using System;
using System.Web.Mvc;
using Moq;
using NUnit.Framework;
using Safal.IncidentTracker.Domain.Abstract;
using Safal.IncidentTracker.Domain.Entities;
using Safal.IncidentTracker.WebUI.Controllers;
using Safal.IncidentTracker.WebUI.HtmlHelpers;

namespace Safal.IncidentTracker.Tests
{
    [TestFixture]
    public class DisplayingPageLinks
    {
        [Test]
        public void Can_Generate_Links_To_Other_Pages()
        {
            // Arrange
            HtmlHelper html = null;
            var mockPagedList = new Mock<IPagedList>();
            mockPagedList.Setup(m => m.CurrentPage).Returns(2);
            mockPagedList.Setup(m => m.TotalCount).Returns(28);
            mockPagedList.Setup(m => m.PageSize).Returns(10);
            mockPagedList.Setup(m => m.TotalPages).Returns(3);

            // Act
            Func<int, string> pageUrl = i => "Page" + i;
            MvcHtmlString result = html.PageLinks(mockPagedList.Object, pageUrl);

            // Assert
            Assert.That(result.ToString(), Is.EqualTo(
                @"<a href=""Page1"">1</a>
<a class=""selected"">2</a>
<a href=""Page3"">3</a>
"));
        }
        
        [Test]
        public void Next_At_End_If_Has_Next_Page()
        {
            // Arrange
            HtmlHelper html = null;
            var mockPagedList = new Mock<IPagedList>();
            mockPagedList.Setup(m => m.CurrentPage).Returns(1);
            mockPagedList.Setup(m => m.TotalCount).Returns(17);
            mockPagedList.Setup(m => m.PageSize).Returns(10);
            mockPagedList.Setup(m => m.TotalPages).Returns(2);
            mockPagedList.Setup(m => m.HasNextPage).Returns(true);
            mockPagedList.Setup(m => m.NextPage).Returns(2);

            // Act
            Func<int, string> pageUrl = i => "Page" + i;
            MvcHtmlString result = html.PageLinks(mockPagedList.Object, pageUrl);

            // Assert
            Assert.That(result.ToString(), Is.EqualTo(
                @"<a class=""selected"">1</a>
<a href=""Page2"">2</a>
<a href=""Page2"">next</a>
"));
        }

        [Test]
        public void Prev_At_Beginning_If_Has_Prev_Page()
        {
            // Arrange
            HtmlHelper html = null;
            var mockPagedList = new Mock<IPagedList>();
            mockPagedList.Setup(m => m.CurrentPage).Returns(2);
            mockPagedList.Setup(m => m.TotalCount).Returns(20);
            mockPagedList.Setup(m => m.PageSize).Returns(10);
            mockPagedList.Setup(m => m.TotalPages).Returns(2);
            mockPagedList.Setup(m => m.HasNextPage).Returns(false);
            mockPagedList.Setup(m => m.HasPreviousPage).Returns(true);
            mockPagedList.Setup(m => m.PreviousPage).Returns(1);

            // Act
            Func<int, string> pageUrl = i => "Page" + i;
            MvcHtmlString result = html.PageLinks(mockPagedList.Object, pageUrl);

            // Assert
            Assert.That(result.ToString(), Is.EqualTo(
                @"<a href=""Page1"">prev</a>
<a href=""Page1"">1</a>
<a class=""selected"">2</a>
"));
        }

        [Test]
        public void Incidents_Lists_Include_Correct_Page_Numbers()
        {
            // Arrange
            Mock<IIncidentsRepository> repository = UnitTestHelpers.MockIncidentsRepository(
                    new Incident { Id = 1, Title = "Fix Machine #1", },
                    new Incident { Id = 2, Title = "Fix Machine #2", },
                    new Incident { Id = 3, Title = "Fix Machine #3", },
                    new Incident { Id = 4, Title = "Fix Machine #4", },
                    new Incident { Id = 5, Title = "Fix Machine #5", }
                );
            var controller = new IncidentsController(repository.Object) { PageSize = 3 };

            // Act
            var result = controller.List(1);

            // Assert
            var viewModel = (PagedList<Incident>)result.ViewData.Model;

            Assert.That(viewModel.CurrentPage, Is.EqualTo(1));
            Assert.That(viewModel.PageSize, Is.EqualTo(3));
            Assert.That(viewModel.TotalCount, Is.EqualTo(5));
            Assert.That(viewModel.TotalPages, Is.EqualTo(2));


        }
    }
}
